package io.shallwe._admin.line;

import cn.hutool.core.date.DateTime;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jfinal.aop.Aop;
import com.jfinal.aop.Before;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.ehcache.CacheKit;
import io.shallwe._admin.basedata.hangerframe.HangerFrameService;
import io.shallwe._admin.basedata.init.StaticMapService;
import io.shallwe._admin.basedata.location.LocationService;
import io.shallwe.common.model.EnterBuffer;
import io.shallwe.common.model.LineInfo;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LineInfoService {
    LineInfo lineInfoDao = new LineInfo().dao();
    HangerFrameService hangerFrameService= Aop.get(HangerFrameService.class);

    /**
     * 列出所有产线信息
     * @return
     */
    public List<LineInfo> listAllLineInfo(){
        List<LineInfo> list = CacheKit.get("listLineInfo","all");
        if(list==null){
            list=lineInfoDao.findAll();
            CacheKit.put("listLineInfo","all",list);
        }
        return  list;
    }

    public void updateAllLineInfo(List<LineInfo> lineInfoList){
        Db.batchUpdate(lineInfoList,lineInfoList.size());
        CacheKit.remove("listLineInfo","all");
        CacheKit.put("listLineInfo","all",lineInfoList);
    }



    public LineInfo findById(Integer id) {
        return lineInfoDao.findById(id);
    }

    public LineInfo findByHangerNo(String hangerNo) {
        String sql="select top 1 * from t_line_info where hanger_no = ?";
        return lineInfoDao.findFirst(sql,hangerNo);
    }


    /***
     * 分页查询
     * @param offset
     * @param pageSize
     * @param traceNo
     * @param hangerNo
     * @return
     */
    public Ret paginate(Integer offset, Integer pageSize, String traceNo, String hangerNo) {
        Integer pageNumber=offset/pageSize+1;
        Kv condition =Kv.by("traceNo", traceNo).set("hangerNo",hangerNo);
        Page<Record> paginate = Db.template("lineInfo.paginate",condition).paginate(pageNumber, pageSize);
        return Ret.ok("total", paginate.getTotalRow()).set("rows", paginate.getList());
    }

    public Ret save(LineInfo lineInfo ) {
        if(isHangerNoExists(lineInfo.getTraceNo(),-1)) {
            return Ret.fail("msg", "电泳框编号已经存在，请输入别的电泳框编号");
        }
        lineInfo.setSort(getSort());
        lineInfo.save();
        return Ret.ok("msg","操作成功");
    }

    public Ret update(LineInfo lineInfo ) {
        if(isHangerNoExists(lineInfo.getHangerNo(),lineInfo.getId())) {
            return Ret.fail("msg", "电泳框编号已经存在，请输入别的电泳框编号");
        }
        lineInfo.update();
        return Ret.ok("msg","操作成功");
    }


    public Ret delete(String id) {
        lineInfoDao.deleteById(id);
        return Ret.ok("msg","操作成功");
    }

    @Before(Tx.class)
    public Ret rackForward(Integer id) {
        LineInfo currentRack = findById(id);
        int currentSort=currentRack.getSort();
        int nextSort=currentSort+1;
        int maxSort = getMaxSort();
        if(currentSort>=maxSort) {
            nextSort=1;
        }
        if(currentSort==nextSort) {
            return Ret.fail("msg","该产线上只有一个电泳框位置");
        }
        LineInfo nextRack = getLineRackBySort(nextSort);
        currentRack.setSort(nextSort);
        nextRack.setSort(currentSort);
        currentRack.update();
        nextRack.update();
        return Ret.ok("msg","操作成功");
    }

    @Before(Tx.class)
    public Ret rackBackward(Integer id) {
        LineInfo currentRack = findById(id);
        int currentSort=currentRack.getSort();
        int lastSort=currentSort-1;
        int maxSort = getMaxSort();
        if(currentSort==1) {
            lastSort=maxSort;
        }
        if(currentSort==lastSort) {
            return Ret.fail("msg","该产线上只有一个电泳框位置");
        }
        LineInfo lastRack = getLineRackBySort(lastSort);
        currentRack.setSort(lastSort);
        lastRack.setSort(currentSort);
        currentRack.update();
        lastRack.update();
        return Ret.ok("msg","操作成功");
    }

    @Before(Tx.class)
    public Ret lineForward() {
        Db.update("update t_line_info set sort=sort+1");
        Db.update("update t_line_info set sort=1 where sort>210");
        return Ret.ok("msg","操作成功");
    }

    public Ret lineBackward() {
        Db.update("update t_line_info set sort=sort-1");
        Db.update("update t_line_info set sort=210 where sort=0");
        return Ret.ok("msg","操作成功");
    }

    public boolean isHangerNoExists(String hangerNo, int id) {
        hangerNo = hangerNo.toLowerCase().trim();
        String sql="select top 1 id from t_line_info where lower(hanger_no)=? and id!=?";
        return Db.queryInt(sql, hangerNo,id)!=null;
    }

    public int getSort() {
        return 1+getMaxSort();
    }

    public int getPosition() {
        return 1;
    }

    public int getMaxSort() {
        Integer maxSort=Db.queryInt("select max(sort) from t_line_info");
        if(null==maxSort) {
            return 0;
        }
        return maxSort;
    }

    public LineInfo getLineRackBySort(int sort) {
        return lineInfoDao.findFirst("select * from t_line_info where sort=?", sort);
    }

    /**
     * 查询最近扫描枪识别到的条码（挂具编号）
     * SELECT 	rack.rackNo  FROM t_line_rack rack
     * LEFT JOIN t_static_rack staticRack ON rack.sort = staticRack.sort
     * LEFT JOIN t_location location ON staticRack.locationCode = location.locationCode
     * where location.locationCode='SCANNER_IN'
     *
     * @return
     */
    public String getLastScanCode(){
        return  Db.template("lineInfo.findLastScanRackNo").queryStr();
    }


    //根据指定的扫描码、挂具编号查询当前挂具所在工位编号
    public String findLocationByScannerCodeAndRackNo(String scannerCode,String hangerNo){
        return hangerFrameService.getHangerLocationMap(scannerCode).get(hangerNo);
    }

    //根据当前自动扫描枪识别到的条码（挂具编号）推算出上次扫描的条码
    public  String getNextScanCode(String scanCode){
       return hangerFrameService.getNextHangerNo(scanCode);
    }
}
